# -*- encoding: utf-8 -*-
"""
App级的共通类
"""

import traceback
import json

from tornado.util import unicode_type
from tornado.escape import utf8
from tornado.web import RequestHandler

from common import config
import settings


class BaseHandler(RequestHandler):
    """ Inherited from tornado.web.RequestHandler
    """
    def __init__(self, application, request, **kwargs):
        super(BaseHandler, self).__init__(application, request, **kwargs)

    def prepare(self):
        self.set_header('Access-Control-Allow-Origin', '*')
        self.set_header('Access-Control-Allow-Methods', 'POST, GET, OPTIONS')
        self.set_header('Access-Control-Allow-Headers', '*')

    def write_error(self, status_code, **kwargs):
        if self.settings.get("serve_traceback") and "exc_info" in kwargs:
            # in debug mode, try to send a traceback
            self.set_header('Content-Type', 'text/plain')
            for line in traceback.format_exception(*kwargs["exc_info"]):
                self.write(line)
            self.finish()
        else:
            if status_code in (405, ):
                error = {'code': '1041', 'msg': config.CODE1041}
            else:
                error = {'code': '1003', 'msg': config.CODE1003}
            response_body = json.dumps(error, ensure_ascii=False)
            response_content_type = 'application/json; charset=UTF-8'
            self.set_header('Content-Type', response_content_type)
            self.set_status(200, 'OK')
            self.write(response_body)
            self.finish()

    def write_api(self, dict_content, code='0', json_ascii=True, json_indent=None):
        chunk = {'code': code}
        if isinstance(dict_content, dict):
            chunk.update(dict_content)
        else:
            type_content = type(dict_content)
            raise TypeError, 'Api content should be dictionary, Not be %s' % type_content

        if self._finished:
            raise RuntimeError("Cannot write() after finish()")
        if not isinstance(chunk, (bytes, unicode_type, dict)):
            message = "write() only accepts bytes, unicode, and dict objects"
            if isinstance(chunk, list):
                message += ". Lists not accepted for security reasons; see http://www.tornadoweb.org/en/stable/web.html#tornado.web.RequestHandler.write"
            raise TypeError(message)
        if isinstance(chunk, dict):
            chunk = json.dumps(chunk, ensure_ascii=json_ascii, indent=json_indent).replace("</", "<\\/")
            self.set_header("Content-Type", "application/json; charset=UTF-8")
        chunk = utf8(chunk)
        self._write_buffer.append(chunk)

    def on_finish(self):
        args = self.request.arguments
        args = {k: v[0] for k, v in args.items()}
        uri = self.request.uri
        path = self.request.path
        ip = self.request.remote_ip
        host = self.request.host


class WebBaseHandler(RequestHandler):
    """ Inherited from tornado.web.RequestHandler
    """
    def __init__(self, application, request, **kwargs):
        super(WebBaseHandler, self).__init__(application, request, **kwargs)

    def prepare(self):
        self.set_header('Access-Control-Allow-Origin', '*')
        self.set_header('Access-Control-Allow-Methods', 'POST, GET, OPTIONS')
        self.set_header('Access-Control-Allow-Headers', '*')

    def write_error(self, status_code, **kwargs):
        if self.settings.get("serve_traceback") and "exc_info" in kwargs:
            # in debug mode, try to send a traceback
            self.set_header('Content-Type', 'text/plain')
            for line in traceback.format_exception(*kwargs["exc_info"]):
                self.write(line)
            self.finish()
        else:
            if status_code in (1024, 1011, 1012):
                error = {'code': 'status_code', 'msg': self._reason.decode('utf-8')}
                devicetype = self.devicetype
            elif status_code == 400:
                error = {'code': '400', 'msg': kwargs["exc_info"][1].log_message}
                devicetype = ''
            else:
                error = {'code': '1003', 'msg': config.CODE1003}
                devicetype = ''
            response_content_type = 'text/html; charset=UTF-8'
            self.set_header('Content-Type', response_content_type)
            self.set_status(200, 'OK')
            self.render('price/weberror.html', error=error, devicetype=devicetype)

    def get_current_user(self):
        user_name = self.get_secure_cookie('user_name', None)
        access_token = self.get_secure_cookie('access_token', None)
        if user_name and access_token:
            user = dict(user_name=user_name, access_token=access_token)
        else:
            user = None
        return user
